﻿using System.Collections.Generic;
using System.Threading.Tasks;
using SolutionUsingBlockUpdates.Common.Commands;
using SolutionUsingBlockUpdates.Model;

namespace SolutionUsingBlockUpdates.ViewModel
{
    public class TimeConsumingProcessViewModel : ViewModelBase
    {
        private readonly TimeConsumingProcessModel _model;
        private bool _uiNeedsUpdate;
        private List<string> _propertyChangedList;
        private Task _uiUpdateTask;

        public TimeConsumingProcessViewModel(TimeConsumingProcessModel model)
        {
            _model = model;
            _model.PropertyChanged += _model_PropertyChanged;
            _propertyChangedList = new List<string>();
        }

        void _model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {

            if (IsValidProperty(e.PropertyName) && !_propertyChangedList.Contains(e.PropertyName))
                _propertyChangedList.Add(e.PropertyName);

            UpDateUI();
        }

        private Task delay;
        private void UpDateUI()
        {
            if (_uiUpdateTask != null && _uiUpdateTask.Status != TaskStatus.RanToCompletion)
                return;
            
            if(delay != null && !delay.IsCompleted)
                return;

            _uiUpdateTask = Task.Factory.StartNew(() =>
                                                      {
                                                          _propertyChangedList.ForEach(OnPropertyChanged);
                                                          delay = Task.Delay(500);
                                                      });
            _uiUpdateTask.Wait();
        }

        private RelayCommand _incrementCounterCommand;
        public RelayCommand IncrementCounterCommand
        {
            get
            {
                return _incrementCounterCommand ?? (_incrementCounterCommand = new RelayCommand(() => _model.IncrementCounter()));
            }
        }

        public int Counter1
        {
            get { return _model.Counter1; }
            set { _model.Counter1 = value; }
        }

        private RelayCommand _decrementCounterCommand;
        public RelayCommand DecrementCounterCommand
        {
            get { return _decrementCounterCommand ?? (_decrementCounterCommand = new RelayCommand(() => _model.DecrementCounter())); }
        }

        public int Counter2
        {
            get { return _model.Counter2; }
            set { _model.Counter2 = value; }
        }

    }
}
